前言
近期在研究近似最近邻算法 HNSW 的源码和论文,这里结合论文中的伪代码做一下 HNSW 主要的几个算法的解读,这将对读懂源码十分有帮助。本文介绍以下算法:
- $\tt INSERT(\it hnsw, q, M, M_{max}, efConstruction, m_L \tt)$ : 新元素 $q$ 插入算法。
- $\tt SEARCH\ LAYER(\it q, ep, ef, l_c \tt)$ : 在第 $l_c$ 层查找距离 $q$ 最近邻的 $ef$ 个元素。
- $\tt SELECT\ NEIGHBORS\ SIMPLE( \it q, C, M \tt) $ : 在候选点集合 $C$ 中 选取距离 $q$ 最近邻的 $M$ 个元素。
- $\tt SELECT\ NEIGHBORS\ HEURISTIC(\it q, C, M, lc, extendCandidates, keepPrunedConnections \tt)$ : 探索式寻找最近邻。
- $\tt KNN\ SEARCH(\it hnsw, q, K, ef \tt)$ : 在 $hnsw$ 索引中查询距离 $q$ 最近邻的 $K$ 个元素。
HNSW 文章:
算法解释
算法一:插入算法
$\tt INSERT(\it hnsw, q, M, M_{max}, efConstruction, m_L \tt)$ : 新元素 $q$ 插入算法。
1 | INSERT(hnsw, q, M, Mmax, efConstruction, mL) |
算法二:搜索当前层的最近邻
$\tt SEARCH\ LAYER(\it q, ep, ef, l_c \tt)$ : 在第 $l_c$ 层查找距离 $q$ 最近邻的 $ef$ 个元素。
1 | SEARCH_LAYER(q, ep, ef, lc) |
算法三:截取集合中最近邻的M个结果
$\tt SELECT\ NEIGHBORS\ SIMPLE( \it q, C, M \tt) $ : 在候选点集合 $C$ 中 选取距离 $q$ 最近邻的 $M$ 个元素。
1 | SELECT_NEIGHBORS_SIMPLE(q, C, M) |
算法四:探索式寻找最近邻
这里理解有点复杂,可以参考我的另一篇文章。近似最近邻算法 HNSW 学习笔记(三)对于启发式近邻选择算法的一些看法
$\tt SELECT\ NEIGHBORS\ HEURISTIC(\it q, C, M, lc, extendCandidates, keepPrunedConnections \tt)$ : 探索式寻找最近邻。
1 | SELECT_NEIGHBORS_HEURISTIC(q, C, M, lc, extendCandidates, keepPrunedConnections) |
算法五:KNN 查询
$\tt KNN\ SEARCH(\it hnsw, q, K, ef \tt)$ : 在 $hnsw$ 索引中查询距离 $q$ 最近邻的 $K$ 个元素。
1 | K-NN-SEARCH(hnsw, q, K, ef) |
尾巴
HNSW 的性能目前来说是十分优秀的,读懂其中的原理,然后能够对源码进行一定的改进是十分有价值的。